package org.xqp.user.service.impl;


import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.xqp.basic.exception.MyException;
import org.xqp.basic.service.impl.BaseServiceImpl;
import org.xqp.basic.util.MD5Utils;
import org.xqp.basic.util.StrUtils;
import org.xqp.user.constant.UserConstant;
import org.xqp.user.domain.Logininfo;
import org.xqp.user.domain.User;
import org.xqp.user.dto.UserDto;
import org.xqp.user.mapper.LogininfoMapper;
import org.xqp.user.mapper.UserMapper;
import org.xqp.user.service.IUserService;

/**
 * 用户注册实现类
 */
@Service
public class UserServiceImpl extends BaseServiceImpl<User> implements IUserService {
    
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private LogininfoMapper logininfoMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    @Transactional
    public void phoneRegister(UserDto userDto) {
        // 第一步前端传过来的数都要进行非空判断
        if (StringUtils.isEmpty(userDto.getPhone()) || StringUtils.isEmpty(userDto.getVerifyCode()) || StringUtils.isEmpty(userDto.getPassword()) || StringUtils.isEmpty(userDto.getPasswordRepeat()) ){
            throw new MyException("必填项不能为空");
        }
        // 第二步电话号码是否注册
        User phone = userMapper.querryByPhone(userDto.getPhone()); // 将前端传过来的电话号码传入数据库查询是否重复
        if (phone!=null){
            throw  new MyException("该电话号码已注册");
        }
        // 第三步判断输入的两次密码是否一致
        if (!userDto.getPassword().equals(userDto.getPasswordRepeat())){
            throw new MyException("两次密码不一致");
        }
        // 第四步判断验证码是否过期
        Object o = redisTemplate.opsForValue().get(UserConstant.REGISTER_PREFIX + userDto.getPhone());
        if (o==null){
            throw new MyException("验证码已过期，请重新获取");
        }
        // 第五步判断前端输入的验证码和后端生成的验证码是否一致
        String code = o.toString().split(":")[1]; //  获取存在redis中的验证码     将o转换为String类型然后以：截断为数组获取其中的验证码
        if(!userDto.getVerifyCode().equalsIgnoreCase(code)){ // equalsIgnoreCase 这个equals比较是不区分大小写
            throw new MyException("验证码错误，请重新输入");
        }
        // 通过UserDto创建User
        User user = userDtoUser(userDto);
        // 通过user创建logininfo对象
        Logininfo logininfo = userLogininfo(user);

        //先添加logininfo  返回自增主键id
        logininfo.setType(1); // 类型是1   先写死
        logininfoMapper.add(logininfo);
        //再添加user 将Logininfo自增主键id也放入user
        user.setLogininfo_id(logininfo.getId());
        userMapper.add(user);
    }
    //通过userDto对象创建User对象
    private User userDtoUser(UserDto userDto){
        User user = new User();
        user.setUsername(userDto.getPhone());
        user.setPhone(userDto.getPhone());
        user.setState(1);
        String salt = StrUtils.getComplexRandomString(32); // 获取盐值
        user.setSalt(salt);
        String password = MD5Utils.encrypByMd5(userDto.getPassword() + salt);// 加密加盐   将密码和盐值字符串拼接后在进行MD5加密
        user.setPassword(password);
        return user;
    }
    //通过user对象创建Logininfo对象
    private Logininfo userLogininfo(User user){
        Logininfo logininfo = new Logininfo();
        BeanUtils.copyProperties(user, logininfo); // 将user中的字段复制到logininfo中
        return logininfo;
    }
}
